home *** CD-ROM | disk | FTP | other *** search
Wrap
/****************************************************************************** MODULE Vars.c DESCRIPTION the vars-module shall support access to different types of variables which are currently "special" vars/flags, "global" vars/flags, "textlocal" vars/flags, "macrolocal" vars and "env" vars also keybindings and menuitems are accessible via variables in some versions of xdme also rexxclips, rexxvars, and macro-bodies might be accessible via the variable interface, but that feature has been dropped due to less feedback (there are some other types used for DME, but not for XDME yet) NOTES This Module is a collection of some types/trees of variables together with their command interface functions; it contains also the standardized access functions to get and set any variable w/ one function. WARNING: as this module is written very close to XDME's internal hierachy; in fact, that means, that funcionality is dropped as soon, as the C-Interpreter is available BUGS none known TODO tell me EXAMPLES SEE ALSO INDEX HISTORY ??-??-9? b_noll created ******************************************************************************/ /************************************** Includes **************************************/ #include "defs.h" /************************************** Global Variables **************************************/ /************************************** Internal Defines & Structures **************************************/ #ifndef SIGN_LOCAL_FLAG # define SIGN_LOCAL_FLAG 't' #endif #define PROC void* /************************************** Internal Variables **************************************/ /************************************** Internal Prototypes **************************************/ /************************************** Macros **************************************/ /************************************** Implementation **************************************/ #ifdef DBASE # define tg DmeBase.gflags # define VarsTree DmeBase.SList #else char tg[MAXTOGGLE/8]; APTR VarsTree = NULL; #endif /* DBASE */ /* ** init_variables() ** initialize the "global" variables structures ** call that function from main or make it '__autoinit' */ //Prototype void init_variables (void); /* void init_variables (void) { VarsTree = NULL; setmem(tg, sizeof(tg), 0); } /* init_variables */ /*************************************************************** ** Access to Environment variables ***************************************************************/ static UBYTE *GetDEnv (const UBYTE *ename) { UBYTE *str = NULL; #ifdef AMIGA long siz; UBYTE buffer[LINE_LENGTH]; if ((siz = GetVar (ename, buffer, LINE_LENGTH, 0)) >= 0) if ((str = malloc (siz + 1))) strcpy (str, buffer); else nomemory(); return str; #endif #ifdef UNIX if ((str = getenv (ename))) if ((str = strdup(str))) return str; else nomemory(); return NULL; #endif } /* GetDEnv */ static void SetDEnv (const UBYTE *ename, const UBYTE *econt) { #ifdef AMIGA SetVar (ename, econt, -1, GVF_GLOBAL_ONLY); #endif #ifdef UNIX setenv (ename, econt, TRUE); #endif } /* SetDEnv */ static UBYTE *GetEnvVar (const UBYTE *name) { UBYTE *str; mountrequest(0); str = GetDEnv(name); mountrequest(1); return str; } /* GetEnvVar */ /*DEFHELP #cmd var SETENV var str -create/modify an enviroment variable (ENV:) */ DEFUSERCMD("SetENV", 2, CF_VWM|CF_COK|CF_ICO, void, do_setenv, (void),) { SetDEnv (av[1], av[2]); } /* do_setenv */ /*DEFHELP #cmd var UNSETENV var -delete an enviroment variable (ENV:) */ DEFUSERCMD("UnsetENV", 1, CF_VWM|CF_COK|CF_ICO, void, do_unsetenv, (void),) { #ifdef AMIGA DeleteVar (av[1], 0); #endif #ifdef UNIX unsetenv(av[1]); #endif } /* do_unsetenv */ DEFVARTREE( 90, "ENV_", VAR_ENV, 4, 4, 0, NULL, NULL, SetDEnv, GetEnvVar ) /*************************************************************** ** Access to the different kinds of Flags ***************************************************************/ /*************************************************************** ** Handling of TEXT Local Flags ***************************************************************/ DEFVARTREE( 30, "TFLAG_", VAR_TF, 6, 6, 0, NULL, NULL, SetTextFlag, GetTextFlag ) Prototype int is_tflagset (int); int is_tflagset (int num) { return IsFlagSet (Ep->textflags, num, MAX_TEXTFLAGS); } /* is_tflagset */ static char SetTextFlag (const UBYTE *name, const UBYTE *value) { return SetFlag (Ep->textflags, name, value, MAX_TEXTFLAGS, "t"); } /* SetTextFlag */ UBYTE *GetTextFlag (const UBYTE *name) { return GetFlag(Ep->textflags, name, MAX_TEXTFLAGS, "t"); } /* GetTextFlag */ /*************************************************************** ** Handling of DME Global Flags ***************************************************************/ DEFVARTREE( 40, "GFLAG_", VAR_GF, 6, 6, 0, NULL, NULL, SetGlobalFlag, GetGlobalFlag ) /* ifdef PATCH_PACK set replace to "g%s" */ Prototype int is_gflagset (int); int is_gflagset (int num) { return IsFlagSet (tg, num, MAXTOGGLE); } /* is_gflagset */ static char SetGlobalFlag (const UBYTE *name, const UBYTE *value) { return SetFlag (tg, name, value, MAXTOGGLE, ""); /* "g" */ } /* SetGlobalFlag */ static UBYTE *GetGlobalFlag (const UBYTE *name) { return GetFlag (tg, name, MAXTOGGLE, ""); /* "g" */ } /* GetGlobalFlag */ /*************************************************************** ** Access to the different kinds of Named Variables ***************************************************************/ /*************************************************************** ** Handling of DME "global" Variables ***************************************************************/ DEFVARTREE( 70, "GVAR_", VAR_GV, 5, 5, VF_COP, &VarsTree, NULL, SetVarIntoTree, GetVarFromTree ) /*static UBYTE *GetDMEVar (const UBYTE *name) { return GetVarFromTree(&VarsTree, name); } /* GetDMEVar */ /*static void SetDMEVar (const UBYTE *name, const UBYTE *value) { SetVarIntoTree (&VarsTree, name, value); } /* SetDMEVar */ /*DEFHELP #cmd var SET var str -create/modify an internal variable */ DEFUSERCMD("Set", 2, CF_VWM|CF_COK|CF_ICO, void, do_set, (void),) { if (!SetGlobalFlag(av[1], av[2])) SetVarIntoTree (&VarsTree, av[1], av[2]); } /* do_set */ /*DEFHELP #cmd var UNSET var -delete an internal variable */ DEFUSERCMD("Unset", 1, CF_VWM|CF_COK|CF_ICO, void, do_unset, (void),) { DelVarFromTree (&VarsTree, av[1]); } /* do_unset */ /*************************************************************** ** Handling of Text Local Variables ***************************************************************/ DEFVARTREE( 60, "TVAR_", VAR_TV, 5, 5, VF_COP|VF_PROJECT, (APTR)(offsetof(ED,textvars)), NULL, SetVarIntoTree, GetVarFromTree ) /*static UBYTE *GetTextVar (const UBYTE *name) { return GetVarFromTree (&Ep->textvars, name); } /* GetTextVar */ /*static void SetTextVar (const UBYTE *name, const UBYTE *value) { SetVarIntoTree (&Ep->textvars, name, value); } /* SetTextVar */ /*DEFHELP #cmd var SETTVAR var str -create/modify a text-local variable */ DEFUSERCMD("SetTVar", 2, CF_VWM|CF_ICO|CF_COK, void, do_settvar, (void),) { if (!SetTextFlag(av[1], av[2])) SetVarIntoTree (&Ep->textvars, av[1], av[2]); } /* do_settvar */ /*DEFHELP #cmd var UNSETTVAR var -delete a text-local variable */ DEFUSERCMD("UnsetTVar", 1, CF_VWM|CF_ICO|CF_COK, void, do_unsettvar, (void),) { DelVarFromTree (&Ep->textvars, av[1]); } /* do_unsettvar */ /*************************************************************** ** Interface to come around with all types of flags ***************************************************************/ static char SetAnyFlag (const UBYTE *name, const UBYTE *qual) { if (name && qual) { if (is_number (name)) { return SetGlobalFlag (name, qual); // } if (!is_digit(name[1])) { /* Commented out for XDME */ // return(SetSpecialVar (name, qual));/* Commented out for XDME */ } else if (name[0] == SIGN_LOCAL_FLAG) { return SetTextFlag(name, qual); } else { /* SET_ABORTION( 1 ); */ return 0; } /* if */ } else { SET_ABORTION( 1 ); return 0; } /* if */ } /* SetAnyFlag */ /*DEFHELP #cmd var FLAG name what -change flag @{B}name@{UB} by @{B}what@{UB} with @{B}name@{UB} is number for a global flag or "t"number for a textlocal flag; @{B}what@{UB} is one of {on, off, toggle, switch, 0, 1, set, reset, true, false}; */ DEFUSERCMD("Flag", 2, CF_VWM|CF_COK|CF_ICO, void, do_flag, (void),) { if (!SetAnyFlag(av[1],av[2])) SET_ABORTION( 1 ); } /* do_flag */ /*DEFHELP #cmd var SETTOGGLE flag -clear toggle entry @{B}flag@{UB} = 0..255|t0..t31 */ DEFUSERCMD("ResetToggle", 1, CF_VWM|CF_COK|CF_ICO, void, do_toggleflag, (void),;) /*DEFHELP #cmd var SETTOGGLE flag -set toggle entry @{B}flag@{UB} = 0..255|t0..t31 */ DEFUSERCMD("SetToggle", 1, CF_VWM|CF_COK|CF_ICO, void, do_toggleflag, (void),;) /*DEFHELP #cmd var SETTOGGLE flag -flip toggle entry @{B}flag@{UB} = 0..255|t0..t31 */ DEFUSERCMD("Toggle", 1, CF_VWM|CF_COK|CF_ICO, void, do_toggleflag, (void),) { SetAnyFlag (av[1], av[0]); } /* do_toggleflag */ DEFVARTREE( 10, "?", VAR_TEST, 1,1, VF_COP|VF_PAW, NULL, NULL, NULL, ExistsAnyVar ) UBYTE *ExistsAnyVar (const UBYTE *name) { UBYTE *buffer; int inter_abort = IS_ABORTED(), type = VAR_NEX; SET_ABORTION( 0 ); if ((buffer = GetTypedVar (name, &type))) { free (buffer); } /* if */ SET_ABORTION(inter_abort); return (type != VAR_NEX)? "1": "0"; } /* ExistsAnyVar */ /************************************************************************* ** ** Interface to be used for external functions and commands ** *************************************************************************/ /* ** the different types of "variables", ** which seem to be possible to be recognized ** ** these definitions must be visible to all modules */ #define VF_COP 1 /* duplicate the result */ #define VF_PAW 2 /* Prefix AlWays: dont use without Prefix */ #define VF_PROJECT 4 /* Userdata is actually offset to Project */ #define VF_UD_FUNC 8 /* Userdata is actually function */ /* do _NEVER_ use VF_PROJECT and VF_UD_FUNC together!!!!! */ typedef struct _vtype { const char *name; /* prefix */ int id; /* number for communication */ int len; /* size of prefix for comparison */ int offset; /* offset to cut prefix */ int flags; /* flags (e.g. duplicate result ...) */ char *replace; /* if prefix matches, replace w/that prefix */ void (*do_set)(UBYTE *, UBYTE *); /* set-function */ UBYTE* (*do_get)(UBYTE *); /* get-function */ APTR userdata; } VTYPE; static VTYPE vartypes[] = { #undef DEFVARTREE #define DEFVARTREE(prio,prefix,id,prelen,precut,flags,ud,replace,set,get) \ prefix,id,prelen,precut,flags,replace,(PROC)set,(PROC)get,ud, //DEFVARTREE( "SHVAR_", VAR_SH , 6, 6, 0, NULL, NULL, NULL ) //DEFVARTREE( "ARP_", VAR_MNX, 4, 4, 0, NULL, NULL, NULL ) //DEFVARTREE( "RXFUNC ", VAR_RXF, 7, 7, 0, NULL, NULL, getQ ) //DEFVARTREE( "RXSFUNC ",VAR_RXF, 8, 8, 0, NULL, NULL, getQ ) //DEFVARTREE( "SFLAG_", VAR_SF, 6, 6, 0, NULL, (void (*)(char*,char*))SetSpecialFlag, GetSpecialFlag ) /* we need 3 names */ //DEFVARTREE( "SINT_", VAR_SI, 5, 5, 0, NULL, (void (*)(char*,char*))SetSpecialInt, GetSpecialInt ) /* for the 3 different types (or we have to put them together) */ //DEFVARTREE( "SPC_", VAR_SV, 4, 4, 0, NULL, (void (*)(char*,char*))SetSpecialVar, GetSpecialVar ) /* of special vars else there are big problems */ //DEFVARTREE( "RXCLP_", VAR_CLP, 6, 6, 0, NULL, SetRexxClip, GetRexxClip ) //DEFVARTREE( "RXVAR_", VAR_RXX, 6, 6, 0, NULL, setrexxvar, getrexxvar ) //DEFVARTREE( "arg", VAR_ARG, 3, 0, VF_PAW, NULL, NULL, NULL, getmacroarg ) //DEFVARTREE( "ARG_", VAR_ARG, 4, 4, VF_PAW, NULL, "arg%s", NULL, getmacroarg ) //DEFVARTREE( "?", VAR_TEST,1, 1, VF_COP|VF_PAW, NULL, NULL, NULL, (PROC)ExistsAnyVar ) /* does a certain variable exist */ //DEFVARTREE( "SPC_", VAR_SV, 4, 4, 0, NULL, NULL, (PROC)SPC_set, (PROC)SPC_get ) /* all spc vars put together */ //DEFVARTREE( "TFLAG_", VAR_TF, 6, 6, 0, NULL, "t%s", (PROC)SetTextFlag, (PROC)GetTextFlag ) //DEFVARTREE( "GFLAG_", VAR_GF, 6, 6, 0, tg, NULL, (PROC)SetGlobalFlag,(PROC)GetGlobalFlag ) /* ifdef PATCH_PACK set replace to "g%s" */ //DEFVARTREE( "MVAR_", VAR_MV, 5, 5,VF_COP|VF_UD_FUNC, GetMVBase, NULL, (PROC)SetVarIntoTree, (PROC)GetVarFromTree ) //DEFVARTREE( "TVAR_", VAR_TV, 5, 5,VF_COP|VF_PROJECT, (APTR)offsetof(ED,textvars), NULL, (PROC)SetVarIntoTree, (PROC)GetVarFromTree ) //DEFVARTREE( "GVAR_", VAR_GV, 5, 5, VF_COP, &VarsTree, NULL, (PROC)SetVarIntoTree, (PROC)GetVarFromTree ) //DEFVARTREE( "LNODE_", VAR_LN, 6, 6, VF_COP, NULL, NULL, (PROC)SetLNode, (PROC)GetLNode ) //DEFVARTREE( "ENV_", VAR_ENV, 4, 4, 0, NULL, NULL, (PROC)SetDEnv, (PROC)GetEnvVar ) //DEFVARTREE( "KEY_", VAR_MAP, 4, 4, VF_COP, NULL, NULL, (PROC)mapkey, (PROC)keyspectomacro ) //DEFVARTREE( "MENU_", VAR_MEN, 5, 5, VF_COP, NULL, NULL, NULL, (PROC)menutomacro ) #include "gen_vtrees.h" /* DEFVARTREE( ff, NULL, VAR_NEX, 0, 0, 0, NULL, NULL, NULL, NULL ) */ }; int check_vtype (char *name, char **rname, int *type) { const VTYPE *vt; for (vt = vartypes; vt->id != VAR_NEX && !IS_ABORTED(); vt++) { if (strncmp(name, vt->name, vt->len) == 0) { *rname = name+vt->offset; if (vt->replace) { sprintf(tmp_buffer, vt->replace, *rname); *rname = tmp_buffer; } /* if prefix replacement */ *type = vt->id; return 1; } /* if */ } /* for */ return 0; } /* check_vtype */ /* ** GetTypedVar() ** this function is nearly the same as getvar from cmd2.c ** major differences: ** * it tells where it has found a variable; ** * first we check if the search-name matches a certain ** type-prefix and if it does, we use that type and its ** result (w/out respect if result != NULL) ** * then we check all types until we get a non-NULL result ** or an abortion ** * the end of the vartypes-list means - there is no variable ** of that name ** (type may be NULL) */ Prototype char *GetTypedVar (const char *find, int *type); char *GetTypedVar (const char *find, int *type) { char *found = NULL; int itype = VAR_NEX; const VTYPE *vt; char inter_abort = IS_ABORTED(); int has_pf = 0; if (type) *type = VAR_NEX; if ((find == NULL)) { SET_ABORTION( 1 ); return NULL; } /* if !name corrupt */ if ((find[0] == '\0')) { /* is it a name ? */ /* we do not set abortcommand here, since this could be a call from a lonely "$" */ return NULL; } /* if name corrupt */ if (globalflags._debug) printf("\tgetvar:oerr/val == %s/%d\n", find, (int)IS_ABORTED()); SET_ABORTION( 0 ); has_pf = check_vtype(find, &find, &itype); for (vt = vartypes; vt->id != VAR_NEX && !IS_ABORTED(); vt++) { if (itype != VAR_NEX && itype != vt->id) continue; if ((itype == VAR_NEX) && (vt->flags & VF_PAW)) continue; if (vt->do_get) { if (vt->userdata) { APTR *inter = vt->userdata; if (vt->flags & VF_PROJECT) inter = (APTR)((ULONG)Ep + (ULONG)inter); if (vt->flags & VF_UD_FUNC) inter = ((APTR (*)(void))inter)(); if (inter) found = ((UBYTE *(*)(APTR, UBYTE *))vt->do_get)(inter, find); } else { found = (*vt->do_get)(find); } /* if */ if (found) { itype = vt->id; if (vt->flags & VF_COP) { found = strdup(found); } /* if dup'd */ goto gv_quit; } /* if res#0 */ } /* if ex det-func */ } /* for all types */ gv_quit: if (globalflags._debug) printf("\tgetvar:prefix/err/val == %s/%d/%s\n",vt->name, (int)IS_ABORTED(), found); SET_ABORTION( IS_ABORTED() || inter_abort ); if (type) *type = itype; return found; } /* GetTypedVar */ /* ** Set a Variable ** if it has a known type, use the associated set-command ** else check if there is a matching prefix ** if nothing fits - abort */ Prototype int SetTypedVar (const char *name, const char *value, int type); int SetTypedVar (const char *name, const char *value, int type) { const VTYPE *vt; if ((name == NULL) || (name[0] == '\0')) { /* is it a name ? */ SET_ABORTION( 1 ); return 0; } /* if name corrupt */ if (type == VAR_NEX) { if (!check_vtype(name, &name, &type)) { SET_ABORTION( 1 ); return 0; } /* if not prefixed */ } /* if unknown type */ for (vt = vartypes; vt->id != VAR_NEX; vt++) { if (vt->id == type) { if (vt->do_set) { char *ptr = name; if (strncmp(ptr, vt->name, vt->len) == 0) { ptr = name+vt->offset; if (vt->replace) { sprintf(tmp_buffer, vt->replace, ptr); ptr = tmp_buffer; } /* if prefix replacement */ } /* if (no) matching prefix */ if (vt->userdata) { APTR *inter = vt->userdata; if (vt->flags & VF_PROJECT) inter = (APTR)((ULONG)Ep + (ULONG)inter); if (vt->flags & VF_UD_FUNC) inter = ((APTR (*)(void))inter)(); if (inter) ((int (*)(APTR, UBYTE *, UBYTE *))vt->do_set)(inter, ptr, value); } else { (*vt->do_set)(ptr, value); } /* if */ return 1; } else { SET_ABORTION( 1 ); return 0; } /* if (no) set-function */ } /* if id found */ } /* for all types */ SET_ABORTION( 1 ); return 0; } /* SetTypedVar */ /* ** Search ** (1) special Variables (2) Flags (3) macro's list, ** (4) text's list, (5) internal list, (6) enviroment, ** (7) Rexx cliplist (8) macros. The variable is allocated ** with malloc(). NULL if not found. ENV: need not exist. */ Prototype char *getvar (const char *find); char *getvar (const char *find) { return GetTypedVar (find, NULL); } /* getvar */ /****************************************************************************** ***** END Vars.c ******************************************************************************/